﻿using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Org.BouncyCastle.Tls.Crypto.Impl.BC;
using TrackSystem.Contracts;
using TrackSystem.Entities.DataShaping;
using TrackSystem.Entities.Dtos.Channel;
using TrackSystem.Entities.Dtos.Var;
using TrackSystem.Entities.Extensions;
using TrackSystem.Entities.Models;
using TrackSystem.Entities.RequestFeatures;
using TrackSystem.IO.Formula;
using TrackSystem.IO.Utils;

namespace TrackSystem.API.Controllers
{
    /// <summary>
    /// 变量控制器
    /// </summary>
    [Route("api/vardef")]
    [ApiController]
    public class VarDefController : ControllerBase
    {
        private readonly IRepositoryWrapper wrapper;
        private readonly ILogger<SensorDefController> logger;
        private readonly IMapper Mapper;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="wrapper"></param>
        /// <param name="logger"></param>
        /// <param name="Mapper"></param>
        public VarDefController(IRepositoryWrapper wrapper,
            ILogger<SensorDefController> logger,
            IMapper Mapper)
        {
            this.wrapper = wrapper;
            this.logger = logger;
            this.Mapper = Mapper;
        }

        /// <summary>
        /// 测试表达式
        /// </summary>
        /// <param name="formula"></param>
        /// <returns></returns>
        [HttpGet("test")]
        public async Task<FormulaResult> TestFormula(string formula)
        {
            var varList = await wrapper.Var.GetNameTypeListAsync();
            var result = ClacuationFormula.TestFormula(formula, varList);
            return result;
        }

        /// <summary>
        /// 获取所有通道信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("all")]
        public async Task<IActionResult> GetAll()
        {
            try
            {
                var result = await wrapper.Var.GetAllListAsync();
                result = result.OrderBy(x => x.Serial)
                    .ThenBy(x => x.snrloopId)
                    .ThenBy(x => x.snrloopIndex)
                    .ThenBy(x => x.Name);
                var vars = Mapper.Map<IEnumerable<VarDto>>(result);

                return Ok(vars);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "[变量设置] 获取异常");
                return StatusCode(StatusCodes.Status500InternalServerError, "[变量设置] 获取异常");
            }
        }
        
        /// <summary>
        /// 获取分页传感器信息
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        [HttpGet("paged")]
        public async Task<IActionResult> GetPaged([FromQuery] RequestParameter parameter)
        {
            try
            {
                var result = await Task.Run(() => wrapper.Var.GetPagedVars(parameter)) ;
                Response.Headers.Append("X-Pagination", Newtonsoft.Json.JsonConvert.SerializeObject(result.MetaData));
                var vars = Mapper.Map<IEnumerable<VarTable>>(result).ShapeData(parameter.Fields);

                return Ok(vars);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "[变量设置] 获取异常");
                return StatusCode(StatusCodes.Status500InternalServerError, "[变量设置] 获取异常");
            }
        }        

        /// <summary>
        /// 获取所有通道信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("sensor/{sensorId:int}")]
        public async Task<IActionResult> GetAllOfSensor(int sensorId)
        {
            try
            {
                var result = await wrapper.Var.GetAllListAsync(a =>
                    (a.Serial == VarSerialEnum.Sensor ||
                     a.Serial == VarSerialEnum.Attr_Sensor) &&
                    a.snrloopId == sensorId);
                    
                var vars = Mapper.Map<IEnumerable<VarDto>>(result);

                return Ok(vars);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "[变量设置] 获取异常");
                return StatusCode(StatusCodes.Status500InternalServerError, "[变量设置] 获取异常");
            }
        }

        /// <summary>
        /// 添加变量
        /// </summary>
        /// <param name="varDto"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<ApiResult<VarDto>> AddVar(VarDto varDto)
        {
            try
            {
                if (varDto == null)
                {
                    return ApiResult<VarDto>.Fail("[变量设置] 变量信息不能为空", StatusCodes.Status400BadRequest);
                }

                var varTable = Mapper.Map<VarTable>(varDto);

                var reuslt = await wrapper.Var.AddVarAsync(varTable);
                return reuslt.Success ? 
                    ApiResult<VarDto>.Ok("[变量设置] 变量信息添加成功") :
                    ApiResult<VarDto>.Fail(reuslt.Message ??= "变量添加失败", StatusCodes.Status400BadRequest);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "[变量设置] 变量信息添加异常");
                return ApiResult<VarDto>.Fail("[变量设置] 变量信息添加异常", StatusCodes.Status500InternalServerError);
            }
        }

        /// <summary>
        /// 更新变量属性
        /// </summary>
        /// <param name="varDto">变量模型视图</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult<VarDto>> UpdateVar(VarDto varDto)
        {
            try
            {
                if (varDto == null)
                {
                    return ApiResult<VarDto>.Fail("[变量设置] 变量信息不能为空", StatusCodes.Status400BadRequest);
                }
                var varTable = Mapper.Map<VarTable>(varDto);
                var reuslt = await wrapper.Var.UpdateVarAsync(varTable);
                if (reuslt.Success)
                {
                    return ApiResult<VarDto>.Ok("[变量设置] 变量信息更新成功");
                }
                else
                {
                    return ApiResult<VarDto>.Fail(reuslt.Message ??= "", StatusCodes.Status400BadRequest);
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "[变量设置] 变量信息更新异常");
                return ApiResult<VarDto>.Fail("[变量设置] 变量信息更新异常", StatusCodes.Status500InternalServerError);
            }
        }

        /// <summary>
        /// 删除变量
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("{id}")]
        public async Task<ApiResult<VarDto>> DeleteVar(int id)
        {
            try
            {
                if (id <= 0)
                {
                    return ApiResult<VarDto>.Fail("[变量设置] 变量ID不能为空", StatusCodes.Status400BadRequest);
                }
                var reuslt = await wrapper.Var.DeleteVarAsync(id);
                if (reuslt.Success)
                {
                    return ApiResult<VarDto>.Ok("[变量设置] 变量信息删除成功");
                }
                else
                {
                    return ApiResult<VarDto>.Fail(reuslt.Message ??= "", StatusCodes.Status400BadRequest);
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "[变量设置] 变量信息删除异常");
                return ApiResult<VarDto>.Fail("[变量设置] 变量信息删除异常", StatusCodes.Status500InternalServerError);
            }
        }
    }
}
